﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SpotlessWeb.ViewHelpers;
using Spotless.Data;



using SpotlessWeb.Helpers;

using Spotless.Services;
using SpotlessWeb.Models;
using System.Web.Security;




namespace SpotlessWeb.Controllers
{
    public class CampaignController : Controller
    {
        public CampaignController () : this(null)
        {
        }

        public CampaignController(Spotless.Services.CampaignService campaignService)
        {
            this.CampaignService = campaignService ?? new Spotless.Services.CampaignService();
        }   

        protected Spotless.Services.CampaignService CampaignService { get; private set; }

        //
        // GET: /Campaign/
        [Authorize(Roles = "Admin")]
        public ActionResult Index(string sort, int? page)
        {
            var data = CampaignService.GetAllCampaigns(sort, page ?? 0, 20);
            return View(data);
            //var data = CampaignService.GetAllCampaigns();
         
        }

        //
        // GET: /Campaign/Details/5
        public ActionResult Details(int id)
        {

            var data = CampaignService.CampaignGetById(id);
            return View(data);
        }

        //
        // GET: /Campaign/Create
        [Authorize(Roles = "Admin")]
        public ActionResult Create()
        {
            ViewData.AddCategories(CampaignService.GetCategories());
            return View();  
        }

        //
        // POST: /Customers/Create
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            var campagin = CampaignService.CreateCampaign();
            //>>>
            
               
            //set product id from dropdown1
            int productId = 0;
            int.TryParse(collection["Campaign.ProductId"], out productId);
            if (productId > 0)
                campagin.ProductId = productId;

            int categoryId = 0;
            int.TryParse(collection["Campaign.CategoryId"], out categoryId);
            if (categoryId > 0)
                campagin.CategoryId  = categoryId;

            TryUpdateModel(campagin, new string[] { "CampaignName", "CampaignDate", "CampaignType", "CategoryId" });

            //TryUpdateModel(campagin);
            
            if (ModelState.IsValid)
            {
                CampaignService.AddUsers(campagin);
                CampaignService.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewData.AddCategories(CampaignService.GetCategories());
            return View(campagin);
        }
        // GET: /Campaign/Edit/5
        public ActionResult Edit(int id)
        {
            var data = CampaignService.CampaignGetById(id);
            
            return View(data);
        }

        //
        // POST: /Campaign/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {

            var campaign = CampaignService.CampaignGetById(id);

            TryUpdateModel(campaign);

            if (ModelState.IsValid)
            {
                CampaignService.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(campaign);
        }

        // GET: /Campaign/Delete/5
        public ActionResult Delete(int id)
        {
            return View();
        }

        // POST: /Campaign/Delete/5
        [HttpPost]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
 
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }


        
        // GET: /Campaign/Recipients/5
        public ActionResult Recipients(int id, string sort, int? page)
        {
            var campaign = CampaignService.CampaignGetById(id);
            
            if(campaign != null)
            {
                var filters = GetRecipientFilters();
                ViewData.SetFilters(filters);
                //var recipeints = CampaignService.GetAllCampaignRecipents(campaign.CampaignId, sort, page ?? 0, 10);
                var recipeints = CampaignService.GetAllCampaignRecipents(campaign.CampaignId, filters.ToDictionary(x => x.Value, x => Request["filter." + x.Key.DisplayName.Replace(" ", "")]), sort, page ?? 0, 30);
                var model = new Models.CampaignRecipientViewModel(campaign, recipeints);
                return View(model);

                //var filters = GetEnquiryFilters();
                
                //var data = QueryService.GetOpenQueries(filters.ToDictionary(x => x.Value, x => Request["filter." + x.Key.DisplayName.Replace(" ", "")]), sort, page ?? 0, 30);
                //return View(recipeints);

            }
            else{return View("NotFound");}
        }

        public ActionResult DownloadRecipients(int id)
        {
            var filters = GetRecipientFilters();

            var recipeints = CampaignService.GetAllCampaignRecipents(id, filters.ToDictionary(x => x.Value, x => Request["filter." + x.Key.DisplayName.Replace(" ", "")]));

            var csv = new ActionResults.CSVActionResult();
            csv.Name = string.Format("Recipients.csv");
            csv.ContentHeaders = GetRecipientsCSVHeaders();

            csv.Rows = recipeints.Select(x => GetRecipientsCSVData(x)).ToList();

            return csv;
        }
        private new Dictionary<FilterExpressionInfo, FilterExpression<CampaignUser>> GetRecipientFilters()
        {
            var firstNameFilterInfo = FilterExpressionInfo.TextBox("First Name");
            var lastNameFilterInfo = FilterExpressionInfo.TextBox("Last Name");
            //var customerResponseFilterInfo = FilterExpressionInfo.TextBox("Customer Response");
            var customerResponseFilterInfo = FilterExpressionInfo.DropDown("Customer Response", new[] { "True", "False"}.Select(x => new SelectListItem() { Text = x.ToString(), Value = x.ToString() }));
            //var emailFilterInfo = FilterExpressionInfo.TextBox("Email");
            //var typeFilterInfo = FilterExpressionInfo.DropDown("Type", SelectListHelpers.GetSelectListFromEnumUsingValues<Spotless.Data.Query.QueryTypes>());
            //var productCategoryFilterInfo = FilterExpressionInfo.DropDown("Product Category", QueryService.GetCategories().Select(x => new SelectListItem() { Text = x.Name, Value = x.CategoryId.ToString() }));
            //var productNameFilterInfo = FilterExpressionInfo.TextBox("Product Name");
            //var sourceFilterInfo = FilterExpressionInfo.DropDown("Source", SelectListHelpers.GetSelectListFromEnumUsingValues<Spotless.Data.Query.QuerySource>());
            //var priorityFilterInfo = FilterExpressionInfo.DropDown("Priority", new[] { 1, 2, 3 }.Select(x => new SelectListItem() { Text = x.ToString(), Value = x.ToString() }));
            //var dateFromFilterInfo = FilterExpressionInfo.TextBox("Date From", new { @class = "dateInput" });
            //var dateToFilterInfo = FilterExpressionInfo.TextBox("Date To", new { @class = "dateInput" });

            return new Dictionary<FilterExpressionInfo, FilterExpression<CampaignUser>>{
                {firstNameFilterInfo, new FilterExpression<CampaignUser>(x => x.Customer.FirstName, FilterTypes.Contains)},
                {lastNameFilterInfo, new FilterExpression<CampaignUser>(x => x.Customer.LastName, FilterTypes.Contains)},
                {customerResponseFilterInfo, new FilterExpression<CampaignUser>(x => x.CustomerResponse, FilterTypes.EqualTo)},
                //{typeFilterInfo, new FilterExpression<Query>(x => x.QueryTypeId, FilterTypes.EqualTo)},
                //{productCategoryFilterInfo, new FilterExpression<Query>(x => x.CategoryId, FilterTypes.EqualTo)},
                //{productNameFilterInfo, new FilterExpression<Query>(x => x.Product.Name, FilterTypes.Contains)},
                //{sourceFilterInfo, new FilterExpression<Query>(x => x.SourceId, FilterTypes.EqualTo)},
                //{priorityFilterInfo, new FilterExpression<Query>(x => x.Priority, FilterTypes.EqualTo)},
                //{dateFromFilterInfo, new FilterExpression<Query>(x => x.EnquiryDate, FilterTypes.GreaterThanOrEqual)},
                //{dateToFilterInfo, new FilterExpression<Query>(x => x.EnquiryDate, FilterTypes.LessThanOrEqual)}
            };
        }

        //
        private string[] GetRecipientsCSVHeaders()
        {
            return new string[]{
                "First Name",
                "Last Name",
                "Customer Response"
            };
        }

        public string[] GetRecipientsCSVData(CampaignUser campaignUser)
        {
            return new string[]{
                campaignUser.Customer.FirstName.ToString(),
                campaignUser.Customer.LastName.ToString(),
                campaignUser.CustomerResponse.ToString()
            };
        }

        //
        public ActionResult DrillDown(int? id, FormCollection collection)
        {
            var data = new Models.CampaignDrillDownViewModel();
            data.AllowEdit = true;
            if (id.HasValue && id.Value > 0)
            {
                data.Campaign = CampaignService.CampaignGetById(id.Value);
            }
            if (data.Campaign== null)
            {
                data.Campaign = new Campaign();
            }
            data.DrillDowns = new DrillDown[0];

            if (collection.AllKeys.Count() > 0)
                SetValuesFromDrillDowns(data.Campaign, collection);

            if (data.Campaign.CategoryId.HasValue && data.Campaign.CategoryId > 0 && (data.Campaign.Category == null || data.Campaign.CategoryId != data.Campaign.Category.CategoryId))
            {
                data.Campaign.Category = CampaignService.GetCategoryById(data.Campaign.CategoryId.Value);
            }

            if (data.Campaign.Category == null)
            {
                data.Categories = CampaignService.GetCategories().ToArray();
            }
            else
            {
                data.Campaign.Product = EnsureDrillDownLoaded(data.Campaign.ProductId, data.Campaign.Product);

                if (data.Campaign.Product == null)
                {
                    data.DrillDowns = CampaignService.GetTopLevelDrillDown(data.Campaign.CategoryId.Value, Spotless.Data.DrillDown.DrillDownTypes.Product).ToArray();
                }
                else
                {
                    data.DrillDowns = CampaignService.GetDrillDownsByParentId(data.Campaign.ProductId.Value, Spotless.Data.DrillDown.DrillDownTypes.Product).ToArray();
                }
            }


            return PartialView("Partial/DrillDown", data);
        }

        private void SetValuesFromDrillDowns(Campaign campaign, FormCollection collection)
        {
            //set drill down values manually
            if (collection["Campaign.CategoryId"] != null)
            {
                campaign.CategoryId = GetIntValue("Campaign.CategoryId", collection) ?? 0;
                if (campaign.CategoryId == 0)
                    ModelState.AddModelError("Campaign.CategoryId", "Category must be selected");
            }

            if (ModelState.IsValid && collection["Campaign.ProductId"] != null)
            {
                campaign.ProductId = GetIntValue("Campaign.ProductId", collection);
                campaign.Product = EnsureDrillDownLoaded(campaign.ProductId, campaign.Product);
                if (campaign.Product == null || campaign.Product.Children.Count(x => x.Type == Spotless.Data.DrillDown.DrillDownTypes.Product) > 0)
                {
                    ModelState.AddModelError("Campaign.ProductId", "Product must be selected");
                }
            }
            else
            {
                campaign.ProductId = null;
                campaign.Product = null;
            }

        }

        private int? GetIntValue(string key, FormCollection collection)
        {
            int val = 0;
            if (int.TryParse(collection[key], out val))
                return val;
            else
                return null;
        }

        private DrillDown EnsureDrillDownLoaded(int? id, DrillDown item)
        {
            if (id > 0 && (item == null || id != item.DrillDownId))
            {
                return CampaignService.GetDrillDownById(id.Value);
            }
            else
            {
                return item;
            }
        }

    }
}
